#ifndef __TIMER_H__
#define __TIMER_H__
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <assert.h>
#include <pthread.h>
#include <sys/time.h>
#include <stdbool.h>

#define TIMER_CNT (10)

#define TIMER_BASIC_INTVL (1)   /* 1s */

#define ES_TINTVL_S (1)
#define ES_TINTVL_US (0)
#define ES_TDELAY_S (0)
#define ES_TDELAY_US (1000)

#define TIMER_NAME_SIZE (128)

#define TM_NOW_GT_NEXT(t1, t2) (t2.tv_sec >= t1.tv_sec) ? 1:0

typedef struct _timer_arg {
    unsigned char tid;
    void *pad;          /* point to anything that you want to pass it to your timer callback function */
}timer_arg_t;

typedef struct _tproc_t {
    char    name[TIMER_NAME_SIZE];  /* name of the timer */
    unsigned char      id;          /* 0 < id <= TIMER_CNT  */
    unsigned int     wait;          /* downcounter for waiting next periodical timer */
    unsigned int     period;        /* maximum conter value for timer interval */
    void    (*pf)(void *);          /* pointer to the executiove function when wait = 0 */
    void    *para;                  /* any type parameters used by pf */

    bool repeat;                    /*  */

    unsigned int period_t;          /* timer interval, ms */
    struct  timeval next_t;         /* the future timer of next schdule, next_t=now+period_t */
} tproc_t;

typedef struct _tsch_t {
    unsigned int     tmap;      /* control if the timer is added. */
    unsigned int     tmask;     /* control if the timer is paused or running, 1:running, 0:paused */
    tproc_t procs[TIMER_CNT];   /* the maximum number of the functions */
} tsch_t;

typedef struct timers_t {
    unsigned int        flag;  /* bit0=1:init flag */
    pthread_mutex_t     lock;
    tsch_t              timers;
} es_timers_t;

void es_timer_init();
int es_timer_start();
void es_timers_add_set(tproc_t *procs, char *name, unsigned int timeout, unsigned int intval, void (* pcb)(void *), void *arg);
int es_timer_add(char* name, unsigned int timeout, unsigned int intval, void (* pcb)(void *), void *arg);
void es_timers_nextsch_set(tproc_t *procs, unsigned int period_t);
void es_timer_sche();
void *es_timer_thread(void *arg);
int es_timer_pause(int tid);
int es_timer_restart(int tid, int interval);
int es_timer_del(char *name);

#endif //__TIMER_H__